iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
Python

進擊的Python系列 第 13

Day13-裝飾器(亞妮)

  • 分享至 

  • xImage
  •  

我喜歡阿爾敏(害羞)!我是亞妮~我分享Python裝飾器

https://ithelp.ithome.com.tw/upload/images/20240818/201632573d8JrF34AV.png
圖片來源:(https://forum.gamer.com.tw/Co.php?bsn=43473&sn=47504)

裝飾器 (Decorator)

一種特殊的函式,允許在不修改原函數定義的情況下,在函數調用前後執行特定的代碼。簡單來說,裝飾器就像是一個函式的「裝飾品」,可以為函式增加額外的功能

  • 為何使用裝飾器?

  • 增加函式功能:計算函式執行時間、記錄函數呼叫紀錄、檢查函式輸入參數等
  • 簡化重複性程式碼:將共用的程式碼抽離到裝飾器中,避免重複寫程式碼
  • AOP (Aspect-Oriented Programming):將橫切 關注點 (cross-cutting concerns) 模組化,例如:日誌記錄、錯誤處理
@decorator_name
def function_to_decorate():
    # function body

@decorator_name:這行語法表示將 decorator_name 裝飾器應用 function_to_decorate 函式

裝飾器基本用法

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper   


@my_decorator
def say_hello():
    print("Hello!")

say_hello()

定義裝飾器函式my_decorator 函式接受一個函式作為參數,並返回一個新的函式 wrapper
創建內部函式wrapper 函式包含了額外的功能,例如在原函式執行前後打印一些訊息
使用 @ 語法@my_decorator 這行代碼表示將 say_hello 函式傳入 my_decorator 函式,並將返回的 wrapper 函式賦給 say_hello

裝飾器工作原理

  • 定義裝飾器函式:這個函式接收一個函式作為參數,並返回一個新的函式
  • 裝飾器函式內部定義一個內嵌函式: 這個內嵌函式會在原函式被調用時執行
  • 內嵌函式中,可以加入額外的程式碼: 例如:在原函式執行前或後打印訊息、檢查參數、計算執行時間
  • 內嵌函式中,呼叫原函式: 將原函式的返回值返回

計算函式執行時間

import time

def timer(func):
    def wrapper_func(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"函式 {func.__name__} 執行時間: {end_time - start_time:.4f} 秒")
        return result
    return wrapper_func

@timer
def my_function(x, y):
    time.sleep(2)  # 模擬耗時操作
    return x + y

result = my_function(3, 4)
print(result)

檢查函式輸入參數

def check_input(func):
    def wrapper_func(*args, **kwargs):
        if args[0] < 0:
            raise ValueError("輸入值不能為負數")
        return func(*args, **kwargs)
    return wrapper_func

@check_input
def calculate_square(x):
    return x * x

result = calculate_square(-2)  # 會拋出 ValueError

帶參數的裝飾器

def repeat(num):
    def decorator(func):
        def wrapper():
            for _ in range(num):
                func()
        return wrapper
    return decorator

@repeat(3)
def greet():
    print("Hello")

帶參數的被裝飾函式

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("函式執行前")
        result = func(*args, **kwargs)
        print("函式執行後")
        return result
    return wrapper

結論

Python 裝飾器是一個強大工具,可以讓程式碼更加簡潔、可讀和可維護
通過理解裝飾器的原理和應用場景,可以更有效地利用這個特性來提升程式設計水平


上一篇
Day12-可疊代(貝爾托特)
下一篇
Day14-生成器(萊納)
系列文
進擊的Python36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言